package io.light.frame.dal.mybatis.generator.core.cfg;

import io.light.frame.dal.mybatis.generator.core.exceptions.InitializationException;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.JdbcType;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * Module generation configuration
 *
 * @author Ivan
 * @version 1.0.0
 * @date 2021-06-13 14:25
 */
@Getter
@Setter
public class ModuleConfiguration {
    private static final String DEFAULT_JAVA_BUILD_PATH = "src/main/java";
    private static final String DEFAULT_RESOURCE_BUILD_PATH = "src/main/resources";
    private static final String DEFAULT_MAPPER_XML_LOCATION = "mapper/autogen";
    public static final String DEFAULT_DESIGN_HOME = "mybatis_design";
    public static final String DEFAULT_MAPPER_NAME_SUFFIX = "Mapper";

    /**
     * Author name
     */
    private String author;

    /**
     * Company name
     */
    private String company;

    /**
     * Module relative path
     */
    private String module;

    /**
     * Datasource bean id
     */
    @Nullable
    private String datasourceBeanId;

    /**
     * Default database
     */
    @Nullable
    private String database;

    /**
     * Design dir
     */
    private String designDir;

    /**
     * Java files build path
     */
    private String javaBuildPath = DEFAULT_JAVA_BUILD_PATH;

    /**
     * Resource files build path
     */
    private String resourceBuildPath = DEFAULT_RESOURCE_BUILD_PATH;

    /**
     * Entity super class
     */
    private String entitySuperClass;

    /**
     * Entity interfaces
     */
    private List<String> entityInterfaces;

    /**
     * Entity class package
     */
    private String entityPackage;

    /**
     * Mapper interface package
     */
    private String mapperPackage;

    /**
     * Mapper name suffix
     */
    private String mapperNameSuffix = DEFAULT_MAPPER_NAME_SUFFIX;

    /**
     * Mapper xml location
     */
    private String mapperXmlLocation = DEFAULT_MAPPER_XML_LOCATION;

    /**
     * {@link JdbcType} -> java {@link Class} mapping
     */
    private Map<JdbcType, Class<?>> typeMapping;

    /**
     * Column data type like 'tinyint(1)' , will be recognized as {@link Boolean} type
     */
    private boolean tinyintCanAsBoolean = true;

    /**
     * Self check
     */
    public void selfCheck() {
        if (StringUtils.isBlank(designDir)) {
            throw new InitializationException("The design xml files dir needs to be specified");
        }
        if (StringUtils.isBlank(javaBuildPath)) {
            throw new InitializationException("The java build path needs to be specified");
        }
        if (StringUtils.isBlank(resourceBuildPath)) {
            throw new InitializationException("The resource build path needs to be specified");
        }
        if (StringUtils.isBlank(entityPackage)) {
            throw new InitializationException("The entity class package needs to be specified");
        }
        if (StringUtils.isBlank(mapperPackage)) {
            throw new InitializationException("The mapper interface package needs to be specified");
        }
        if (StringUtils.isBlank(mapperXmlLocation)) {
            throw new InitializationException("The mapper xml location needs to be specified");
        }
    }


    /**
     * Self check
     *
     * @param merger merger
     */
    public void selfCheck(ModuleConfiguration merger) {
        if (merger != null && merger != this) {
            if (StringUtils.isBlank(datasourceBeanId)) {
                this.datasourceBeanId = merger.getDatasourceBeanId();
            }
            if (StringUtils.isBlank(author)) {
                this.author = merger.getAuthor();
            }
            if (StringUtils.isBlank(company)) {
                this.company = merger.getCompany();
            }
            if (StringUtils.isBlank(javaBuildPath)) {
                this.javaBuildPath = merger.getJavaBuildPath();
            }
            if (StringUtils.isBlank(resourceBuildPath)) {
                this.resourceBuildPath = merger.getResourceBuildPath();
            }
            if (StringUtils.isBlank(entityPackage)) {
                this.entityPackage = merger.getEntityPackage();
            }
            if (StringUtils.isBlank(mapperPackage)) {
                this.mapperPackage = merger.getMapperPackage();
            }
            if (StringUtils.isBlank(mapperXmlLocation)) {
                this.mapperXmlLocation = merger.getMapperXmlLocation();
            }
            if (CollectionUtils.isEmpty(typeMapping)) {
                if (merger instanceof GeneratorConfiguration) {
                    GeneratorConfiguration rootConfig = (GeneratorConfiguration) merger;
                    if (rootConfig.isShareTypeMapping()) {
                        this.typeMapping = rootConfig.getTypeMapping();
                    }
                }
            }
        }
        selfCheck();
    }
}
